﻿using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;
using Red.Controls;
using Red.Controls.Utils;
using Red.Controls.ViewModels;
using Red.Core.Extensions;
using Red.Launcher.Utilities;
using Database = Red.Launcher.ViewModels.Workspaces.Database;
using P4 = Red.Core.Perforce;

namespace Red.Launcher.Menus.Workspaces.Admin
{
    public partial class Specifications : UserControl
    {
        #region Private Data

        private CommandPalette _streamPicker = new CommandPalette();

        #endregion Private Data

        #region Public Properties

        public bool IsValid
        {
            get
            {
                bool isValid = true;

                isValid &= Helpers.ValidateElement( _displayName );
                isValid &= Helpers.ValidateElement( _clientName );
                isValid &= Helpers.ValidateElement( _stream );

                return isValid;
            }
        }

        public P4.Mediator Mediator { get; set; }

        #endregion Public Properties

        #region C-Tor

        public Specifications()
        {
            InitializeComponent();
        }

        #endregion C-Tor

        #region Public Methods

        public void RefreshBindingsForValidation()
        {
            Helpers.RefreshBindingValues( _displayName, TextBox.TextProperty );
            Helpers.RefreshBindingValues( _clientName, TextBox.TextProperty );
            Helpers.RefreshBindingValues( _stream, ButtonTextbox.TextProperty );
        }

        #endregion Public Methods

        #region Private Methods
        
        private async Task< IEnumerable<P4.Stream> > GetStreams()
        {
            if ( Mediator != null && await Mediator.SignInCheckAndPrompt() )
            {
                return Mediator.GetStreams();
            }

            return null;
        }

        #endregion Private Methods

        #region Event Handlers

        private void SearchStreams_Selected( object sender, string stream )
        {
            _stream.Text = stream;
        }

        private void SearchStreams_CanExecute( object sender, CanExecuteRoutedEventArgs e )
        {
            e.CanExecute = !_streamPicker.IsVisible;
        }

        private async void SearchStreams_Executed( object sender, ExecutedRoutedEventArgs e )
        {
            IEnumerable<P4.Stream> streams = await GetStreams();

            List<CommandPaletteItem> items = new List<CommandPaletteItem>();

            if ( streams != null )
            {
                foreach ( var stream in streams )
                {
                    CommandPaletteItem<string> item = new CommandPaletteItem<string>( stream.Id )
                    {
                        Name = stream.Name,
                        Comment = stream.Id
                    };

                    item.Click += SearchStreams_Selected;
                    items.Add( item );
                }
            }

            _streamPicker.Items = items;

            _streamPicker.SetPositionRelativeTo( _stream );

            _streamPicker.Show();
        }

        #endregion Event Handlers

        private void StreamFilter_Resize( double xDelta, double yDelta )
        {
            if ( _streamFilter.Height + yDelta > 0 )
            {
                _streamFilter.Height += yDelta;
            }
        }
    }

    #region Validation Rules

    public class ContainsValidPerforceWorkspaceCharactersRule : ValidationRule
    {
        public override ValidationResult Validate( object value, System.Globalization.CultureInfo cultureInfo )
        {
            string valueStr = (string)value;

            if ( Regex.IsMatch( valueStr, @"[^\x00-\x7F]" ) )
            {
                return new ValidationResult( false, "Field may not contain non-ascii characters" );
            }

            if ( Regex.IsMatch( valueStr, Database.P4ClientSpecification.INVALIDCHARS_REGEX ) )
            {
                return new ValidationResult( false, "Field may only contain a-z A-Z _ ." );
            }

            return new ValidationResult( true, null );
        }
    }

    #endregion Validation Rules
}
